{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bb04f1a2-1f87-42e6-a5ad-453eec40215f",
   "metadata": {},
   "source": [
    "# Models API\n",
    "\n",
    "使用 Models API 查看和访问 OpenAI 提供的预训练大语言模型"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7466990e-c2ac-441c-a545-fdc122e752ca",
   "metadata": {},
   "source": [
    "## List Models\n",
    "\n",
    "列出当前可用的模型，并提供每个模型的基本信息，如所有者和可用性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f453ab0c-b262-4fa5-993e-b4b341e46a94",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "client = OpenAI()\n",
    "\n",
    "models = client.models.list()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "87dbc132-41cd-4ebc-928f-9edf6a4befcd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SyncPage[Model](data=[Model(id='gpt-3.5-turbo-1106', created=1698959748, object='model', owned_by='system'), Model(id='dall-e-3', created=1698785189, object='model', owned_by='system'), Model(id='gpt-4-0613', created=1686588896, object='model', owned_by='openai'), Model(id='dall-e-2', created=1698798177, object='model', owned_by='system'), Model(id='gpt-3.5-turbo-0125', created=1706048358, object='model', owned_by='system'), Model(id='gpt-4', created=1687882411, object='model', owned_by='openai'), Model(id='whisper-1', created=1677532384, object='model', owned_by='openai-internal'), Model(id='tts-1-hd-1106', created=1699053533, object='model', owned_by='system'), Model(id='gpt-3.5-turbo', created=1677610602, object='model', owned_by='openai'), Model(id='tts-1-hd', created=1699046015, object='model', owned_by='system'), Model(id='gpt-4-0125-preview', created=1706037612, object='model', owned_by='system'), Model(id='gpt-4-turbo-preview', created=1706037777, object='model', owned_by='system'), Model(id='text-embedding-3-large', created=1705953180, object='model', owned_by='system'), Model(id='gpt-3.5-turbo-0301', created=1677649963, object='model', owned_by='openai'), Model(id='gpt-3.5-turbo-0613', created=1686587434, object='model', owned_by='openai'), Model(id='gpt-4-vision-preview', created=1698894917, object='model', owned_by='system'), Model(id='gpt-3.5-turbo-16k-0613', created=1685474247, object='model', owned_by='openai'), Model(id='gpt-3.5-turbo-16k', created=1683758102, object='model', owned_by='openai-internal'), Model(id='gpt-4-1106-preview', created=1698957206, object='model', owned_by='system'), Model(id='gpt-3.5-turbo-instruct', created=1692901427, object='model', owned_by='system'), Model(id='gpt-3.5-turbo-instruct-0914', created=1694122472, object='model', owned_by='system'), Model(id='tts-1', created=1681940951, object='model', owned_by='openai-internal'), Model(id='davinci-002', created=1692634301, object='model', owned_by='system'), Model(id='babbage-002', created=1692634615, object='model', owned_by='system'), Model(id='tts-1-1106', created=1699053241, object='model', owned_by='system'), Model(id='text-embedding-ada-002', created=1671217299, object='model', owned_by='openai-internal'), Model(id='text-embedding-3-small', created=1705948997, object='model', owned_by='system')], object='list')\n"
     ]
    }
   ],
   "source": [
    "print(models)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b69d74e-a79d-4832-9bda-2a5b9df7e68d",
   "metadata": {},
   "source": [
    "#### 查看 OpenAI 最新提供的模型 API 信息\n",
    "\n",
    "`models.data`: 目前OpenAI提供的大语言模型列表，列表中的每一项都对应着一个模型实例。\n",
    "\n",
    "以`GPT-3.5-Turbo`模型为例，解释说明各项参数：\n",
    "\n",
    "1. `created`: 这是模型创建的时间戳，单位为 Unix 时间戳（自1970年1月1日（00:00:00 GMT）以后的秒数）。\n",
    "2. `id`: 这是模型的唯一标识符。在这个例子中，模型的 ID 是 \"text-davinci-003\"。\n",
    "3. `object`: 这个字段表示的是当前对象的类型，在这个例子中，对象是 \"model\"，说明这个 JSON 对象是一个模型。\n",
    "4. `owned_by`: 这个字段表示的是模型的所有者，在这个例子中，模型的所有者是 \"openai-internal\"。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "82922dd9-f38e-4ec1-8be0-361aefb99d7b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Model(id='gpt-3.5-turbo-1106', created=1698959748, object='model', owned_by='system'),\n",
       " Model(id='dall-e-3', created=1698785189, object='model', owned_by='system'),\n",
       " Model(id='gpt-4-0613', created=1686588896, object='model', owned_by='openai'),\n",
       " Model(id='dall-e-2', created=1698798177, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo-0125', created=1706048358, object='model', owned_by='system'),\n",
       " Model(id='gpt-4', created=1687882411, object='model', owned_by='openai'),\n",
       " Model(id='whisper-1', created=1677532384, object='model', owned_by='openai-internal'),\n",
       " Model(id='tts-1-hd-1106', created=1699053533, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo', created=1677610602, object='model', owned_by='openai'),\n",
       " Model(id='tts-1-hd', created=1699046015, object='model', owned_by='system'),\n",
       " Model(id='gpt-4-0125-preview', created=1706037612, object='model', owned_by='system'),\n",
       " Model(id='gpt-4-turbo-preview', created=1706037777, object='model', owned_by='system'),\n",
       " Model(id='text-embedding-3-large', created=1705953180, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo-0301', created=1677649963, object='model', owned_by='openai'),\n",
       " Model(id='gpt-3.5-turbo-0613', created=1686587434, object='model', owned_by='openai'),\n",
       " Model(id='gpt-4-vision-preview', created=1698894917, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo-16k-0613', created=1685474247, object='model', owned_by='openai'),\n",
       " Model(id='gpt-3.5-turbo-16k', created=1683758102, object='model', owned_by='openai-internal'),\n",
       " Model(id='gpt-4-1106-preview', created=1698957206, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo-instruct', created=1692901427, object='model', owned_by='system'),\n",
       " Model(id='gpt-3.5-turbo-instruct-0914', created=1694122472, object='model', owned_by='system'),\n",
       " Model(id='tts-1', created=1681940951, object='model', owned_by='openai-internal'),\n",
       " Model(id='davinci-002', created=1692634301, object='model', owned_by='system'),\n",
       " Model(id='babbage-002', created=1692634615, object='model', owned_by='system'),\n",
       " Model(id='tts-1-1106', created=1699053241, object='model', owned_by='system'),\n",
       " Model(id='text-embedding-ada-002', created=1671217299, object='model', owned_by='openai-internal'),\n",
       " Model(id='text-embedding-3-small', created=1705948997, object='model', owned_by='system')]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "models.data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "774e3a12-01f6-44ad-8829-03510f5d9df6",
   "metadata": {},
   "source": [
    "### 获取模型 ID 列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "dd351597-b055-4d30-aa0b-b5e468f7b924",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'gpt-3.5-turbo-1106'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "models.data[0].id"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "fdb8752e-bcb8-4732-a037-1835861c20a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "model_list = [model.id for model in models.data]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3372f33d-4302-4fc6-9eac-e1d34cf216be",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['gpt-3.5-turbo-1106', 'dall-e-3', 'gpt-4-0613', 'dall-e-2', 'gpt-3.5-turbo-0125', 'gpt-4', 'whisper-1', 'tts-1-hd-1106', 'gpt-3.5-turbo', 'tts-1-hd', 'gpt-4-0125-preview', 'gpt-4-turbo-preview', 'text-embedding-3-large', 'gpt-3.5-turbo-0301', 'gpt-3.5-turbo-0613', 'gpt-4-vision-preview', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-16k', 'gpt-4-1106-preview', 'gpt-3.5-turbo-instruct', 'gpt-3.5-turbo-instruct-0914', 'tts-1', 'davinci-002', 'babbage-002', 'tts-1-1106', 'text-embedding-ada-002', 'text-embedding-3-small']\n"
     ]
    }
   ],
   "source": [
    "print(model_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75d2a270-949c-4ad2-a568-e254e6231333",
   "metadata": {},
   "source": [
    "## Retrieve Model\n",
    "\n",
    "根据前面查询到当前支持的模型ID列表，获取指定模型实例，如`gpt-3.5-turbo`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6fd7eca9-ed5a-4bca-8f9c-a0bf36177d31",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "client = OpenAI()\n",
    "\n",
    "# 将模型 ID 传入 retrieve 接口\n",
    "gpt_3 = client.models.retrieve(\"gpt-3.5-turbo\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "51078b58-67db-467a-b09f-ef40562f1fad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model(id='gpt-3.5-turbo', created=1677610602, object='model', owned_by='openai')\n"
     ]
    }
   ],
   "source": [
    "print(gpt_3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67bd0916-d771-4745-85bb-28be33806d89",
   "metadata": {},
   "source": [
    "### 获取指定模型，如 GPT-4V"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2ea16de8-add9-4ad4-b5b9-ebb959d7ab7f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Model(id='gpt-4-vision-preview', created=1698894917, object='model', owned_by='system')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "client.models.retrieve(\"gpt-4-vision-preview\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fa107114-28cd-435a-a4b0-c9ceabddf415",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "028f4f7e-3be1-44d7-bfcd-c65a13e85093",
   "metadata": {},
   "source": [
    "# 文本内容补全初探（Completions API）[Legacy]\n",
    "\n",
    "使用 Completions API 实现各类文本生成任务\n",
    "\n",
    "\n",
    "主要请求参数说明：\n",
    "\n",
    "\n",
    "- **`model`** （string，必填）\n",
    "\n",
    "  要使用的模型的 ID。可以参考 **模型端点兼容性表**。\n",
    "\n",
    "- **`prompt`** （string or array，必填，Defaults to ）\n",
    "\n",
    "  生成补全的提示，编码为字符串、字符串数组、token数组或token数组数组。\n",
    "\n",
    "  注意，这是模型在训练过程中看到的文档分隔符，所以如果没有指定提示符，模型将像从新文档的开头一样生成。\n",
    "\n",
    "- **`stream`** （boolean，选填，默认 false）\n",
    "\n",
    "  当它设置为 true 时，API 会以 SSE（ Server Side Event ）方式返回内容，即会不断地输出内容直到完成响应，流通过 `data: [DONE]` 消息终止。\n",
    "\n",
    "- **`max_tokens`** （integer，选填，默认是 16）\n",
    "\n",
    "  补全时要生成的最大 token 数。\n",
    "\n",
    "  提示 `max_tokens` 的 token 计数不能超过模型的上下文长度。大多数模型的上下文长度为 2048 个token（最新模型除外，它支持 4096）\n",
    "\n",
    "- **`temperature`** （number，选填，默认是1）\n",
    "\n",
    "  使用哪个采样温度，在 **0和2之间**。\n",
    "\n",
    "  较高的值，如0.8会使输出更随机，而较低的值，如0.2会使其更加集中和确定性。\n",
    "\n",
    "  通常建议修改这个（`temperature` ）或 `top_p` 但两者不能同时存在，二选一。\n",
    "\n",
    "- **`n`** （integer，选填，默认为 1）\n",
    "\n",
    "  每个 `prompt` 生成的补全次数。\n",
    "\n",
    "  注意：由于此参数会生成许多补全，因此它会快速消耗token配额。小心使用，并确保对 `max_tokens` 和 `stop` 进行合理的设置。\n",
    "\n",
    "\n",
    "## 生成英文文本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0526acb1-5741-48b6-ae64-917ad0d064b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI()\n",
    "\n",
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"Say this is a test\",\n",
    "  max_tokens=7,\n",
    "  temperature=0\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "af7a8d1f-c2f7-421d-bd0d-0890d06a0c34",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Completion(id='cmpl-96Xg9PBBvjNfJRAEC6O0uHOCqZdGv', choices=[CompletionChoice(finish_reason='stop', index=0, logprobs=None, text='\\n\\nThis is a test.')], created=1711346457, model='gpt-3.5-turbo-instruct', object='text_completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=6, prompt_tokens=5, total_tokens=11))\n"
     ]
    }
   ],
   "source": [
    "print(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "63cddd0f-a8f3-4f62-891a-8146306a5d95",
   "metadata": {},
   "outputs": [],
   "source": [
    "text = data.choices[0].text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "49cbd498-bfa5-4d11-a6ee-30822b24dcc8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "This is a test.\n"
     ]
    }
   ],
   "source": [
    "print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c43d83bd-375f-4256-925a-e894d0e155a0",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "159f1bf9-1604-414c-af74-45b22c33a7f9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "5c79be11-b2b4-4580-ad10-b7111cb950ea",
   "metadata": {},
   "source": [
    "## 生成中文文本\n",
    "\n",
    "调整 `max_tokens` "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3e3a4018-7c72-49a1-942b-167c3941fb96",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"讲10个给程序员听得笑话\",\n",
    "  max_tokens=1000,\n",
    "  temperature=0.5\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f04959ba-5781-4e9e-bdfb-a55f0698acd9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "1. Why did the programmer quit his job? Because he didn't get arrays.\n",
      "\n",
      "2. How many programmers does it take to change a lightbulb? None, that's a hardware problem.\n",
      "\n",
      "3. Why do programmers prefer dark mode? Because light attracts bugs.\n",
      "\n",
      "4. What do you call a programmer who doesn't comment their code? A code ninja, because you can't see them.\n",
      "\n",
      "5. Why was the JavaScript developer sad? Because he didn't know how to 'null' his feelings.\n",
      "\n",
      "6. What did the programmer say when he found a bug? \"It's not a bug, it's a feature!\"\n",
      "\n",
      "7. Why did the programmer go broke? Because he used up all his cache.\n",
      "\n",
      "8. How do you know if a programmer is an extrovert? They look at your shoes instead of their own when talking to you.\n",
      "\n",
      "9. Why do programmers prefer dark chocolate? Because it's the closest thing to dark mode.\n",
      "\n",
      "10. How do you comfort a JavaScript bug? You console it.\n"
     ]
    }
   ],
   "source": [
    "text = data.choices[0].text\n",
    "print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad54c353-64bf-44dc-ad55-1d2c4a783443",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "3e5bdaff-764f-4fbf-b2c2-a8afbdaca8c6",
   "metadata": {},
   "source": [
    "## 生成 Python 代码，并执行和验证\n",
    "\n",
    "以面试中考察的典型的试题 `快速排序` 为例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "3d5a6a51-57cd-4890-8978-b07efa2c28e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"生成可执行的快速排序 Python 代码\",\n",
    "  max_tokens=1000,\n",
    "  temperature=0\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "45e24e7d-72d7-491a-a60f-0e8031a6fc7d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "def quick_sort(arr):\n",
      "    if len(arr) <= 1:\n",
      "        return arr\n",
      "    pivot = arr[0]\n",
      "    left = [x for x in arr[1:] if x <= pivot]\n",
      "    right = [x for x in arr[1:] if x > pivot]\n",
      "    return quick_sort(left) + [pivot] + quick_sort(right)\n"
     ]
    }
   ],
   "source": [
    "text = data.choices[0].text\n",
    "print(text)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49c6675c-611e-4933-9fca-804200eef339",
   "metadata": {},
   "source": [
    "#### Prompt：Jupyter Notebook 中执行生成的代码\n",
    "\n",
    "Prompt：\n",
    "\n",
    "```\n",
    "我现在用 Completion API 生成了 Python 代码，并以字符串形式存放在 text 中，如下所示：\n",
    "\n",
    "text = data.choices[0].text\n",
    "print(text)\n",
    "\n",
    "def quick_sort(arr):\n",
    "    if len(arr) <= 1:\n",
    "        return arr\n",
    "    pivot = arr[0]\n",
    "    left = [x for x in arr[1:] if x <= pivot]\n",
    "    right = [x for x in arr[1:] if x > pivot]\n",
    "    return quick_sort(left) + [pivot] + quick_sort(right)\n",
    "\n",
    "如何在 Jupyter notebook 中执行text中存放的这段代码\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "21707523-bde6-48b9-ac9d-da693045f7c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# `exec` 函数会执行传入的字符串作为 Python 代码。\n",
    "# 在这个例子中，我们使用 `exec` 来定义了一个 `quick_sort` 函数，然后你就可以调用这个函数了。\n",
    "# 请注意，`exec` 可以执行任何 Python 代码，因此在使用它的时候一定要小心，特别是当你执行的代码来自不可信的来源时。\n",
    "exec(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "15918392-560b-4826-8800-4c7a11167579",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 1, 2, 3, 6, 8, 10, 12]\n"
     ]
    }
   ],
   "source": [
    "# 现在你可以调用这个函数了\n",
    "print(quick_sort([12,3,6,8,10,1,2,1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd669a78-125f-478f-b3d9-677f137d9398",
   "metadata": {},
   "source": [
    "# 聊天机器人初探（Chat Completions API）\n",
    "\n",
    "使用 Chat Completions API 实现对话任务\n",
    "\n",
    "聊天补全(Chat Completions API)以消息列表作为输入，并返回模型生成的消息作为输出。尽管聊天格式旨在使多轮对话变得简单，但它同样适用于没有任何对话的单轮任务。\n",
    "\n",
    "主要请求参数说明：\n",
    "\n",
    "\n",
    "- **`model` （string，必填）**\n",
    "\n",
    "  要使用的模型ID。有关哪些模型适用于Chat API的详细信息\n",
    "\n",
    "- **`messages` （array，必填）**\n",
    "\n",
    "  迄今为止描述对话的消息列表\n",
    "    - **`role` （string，必填）**\n",
    "\n",
    "  发送此消息的角色。`system` 、`user` 或 `assistant` 之一（一般用 user 发送用户问题，system 发送给模型提示信息）\n",
    "\n",
    "    - **`content` （string，必填）**\n",
    "    \n",
    "      消息的内容\n",
    "    \n",
    "    - **`name` （string，选填）**\n",
    "    \n",
    "      此消息的发送者姓名。可以包含 a-z、A-Z、0-9 和下划线，最大长度为 64 个字符\n",
    "\n",
    "- **`stream` （boolean，选填，是否按流的方式发送内容）**\n",
    "\n",
    "  当它设置为 true 时，API 会以 SSE（ Server Side Event ）方式返回内容。SSE 本质上是一个长链接，会持续不断地输出内容直到完成响应。如果不是做实时聊天，默认false即可。\n",
    "\n",
    "- **`max_tokens` （integer，选填）**\n",
    "\n",
    "  在聊天补全中生成的最大 **tokens** 数。\n",
    "\n",
    "  输入token和生成的token的总长度受模型上下文长度的限制。\n",
    "\n",
    "- **`temperature` （number，选填，默认是 1）**\n",
    "\n",
    "  采样温度，在 0和 2 之间。\n",
    "\n",
    "  较高的值，如0.8会使输出更随机，而较低的值，如0.2会使其更加集中和确定性。\n",
    "\n",
    "  通常建议修改这个（`temperature` ）或者 `top_p` ，但两者不能同时存在，二选一。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d00108e4-b98e-4d55-a1e2-78845b321fec",
   "metadata": {},
   "source": [
    "## 开启聊天模式\n",
    "\n",
    "使用 `messages` 记录迄今为止对话的消息列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "172f2eb6-2d2b-4d10-9887-5e4af011c77f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "client = OpenAI()\n",
    "\n",
    "messages=[\n",
    "    {\n",
    "        \"role\": \"user\", \n",
    "        \"content\": \"Hello!\"\n",
    "    }\n",
    "]\n",
    "\n",
    "\n",
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages = messages\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "158a8a3b-0a73-4157-9025-8282527fd692",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChatCompletion(id='chatcmpl-96XgFpOGJq8wc1w8PKjW2wLmHqnSd', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='Hello! How can I assist you today?', role='assistant', function_call=None, tool_calls=None))], created=1711346463, model='gpt-3.5-turbo-0125', object='chat.completion', system_fingerprint='fp_3bc1b5746c', usage=CompletionUsage(completion_tokens=9, prompt_tokens=9, total_tokens=18))\n"
     ]
    }
   ],
   "source": [
    "print(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d872f47e-b768-4d3e-850f-c2034e2e2263",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChatCompletionMessage(content='Hello! How can I assist you today?', role='assistant', function_call=None, tool_calls=None)\n"
     ]
    }
   ],
   "source": [
    "# 从返回的数据中获取生成的消息\n",
    "new_message = data.choices[0].message\n",
    "# 打印 new_message\n",
    "print(new_message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "ee8c6048-2fed-4a81-90cc-45f526630aad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'role': 'user', 'content': 'Hello!'}, ChatCompletionMessage(content='Hello! How can I assist you today?', role='assistant', function_call=None, tool_calls=None)]\n"
     ]
    }
   ],
   "source": [
    "# 将消息追加到 messages 列表中\n",
    "messages.append(new_message)\n",
    "print(messages)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "1f88a3a6-c6ad-47a2-a187-40f4e921b54f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "openai.types.chat.chat_completion_message.ChatCompletionMessage"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(new_message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "4dc4a02b-2c19-4114-bfad-7b8364d1f8fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'assistant'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_message.role"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "843e1454-85b9-409f-8a6a-c84fadcab05a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello! How can I assist you today?'"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_message.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "626586e5-55c0-4b1c-8dc4-175edab9b7c4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ChatCompletionMessage(content='Hello! How can I assist you today?', role='assistant', function_call=None, tool_calls=None)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "bbf5b445-f0b2-422c-befd-2738982903d4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'role': 'user', 'content': 'Hello!'}]\n"
     ]
    }
   ],
   "source": [
    "print(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5a9d6f7b-09fd-4bed-bcde-2ab50d3d415c",
   "metadata": {},
   "source": [
    "#### Prompt: OpenAIObject -> Dict\n",
    "\n",
    "```\n",
    "打印 messages 列表后发现数据类型不对，messages 输出如下：\n",
    "\n",
    "print(messages)\n",
    "\n",
    "[{'role': 'user', 'content': 'Hello!'}, <OpenAIObject at 0x7f27582c13f0> JSON: {\n",
    "  \"content\": \"Hello! How can I assist you today?\",\n",
    "  \"role\": \"assistant\"\n",
    "}]\n",
    "\n",
    "将OpenAIObject 转换为一个如下数据类型格式：\n",
    "\n",
    "    {\n",
    "        \"role\": \"user\", \n",
    "        \"content\": \"Hello!\"\n",
    "    }\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "8d9052f8-88ef-4b71-8fa8-42bff7304537",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_message = data.choices[0].message\n",
    "new_message_dict = {\"role\": new_message.role, \"content\": new_message.content}\n",
    "type(new_message_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "699416f3-ee26-432a-8ad5-27b151f24846",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'role': 'assistant', 'content': 'Hello! How can I assist you today?'}\n"
     ]
    }
   ],
   "source": [
    "print(new_message_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "7a11a2c6-3f2b-4c35-b987-f396f839da7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将消息追加到 messages 列表中\n",
    "messages.append(new_message_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "532671cb-6ceb-472f-98c8-c86a38c08bc6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'role': 'user', 'content': 'Hello!'}, {'role': 'assistant', 'content': 'Hello! How can I assist you today?'}]\n"
     ]
    }
   ],
   "source": [
    "print(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7a5d741-5b2e-4f1a-8a74-e3b559874079",
   "metadata": {},
   "source": [
    "#### 新一轮对话"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "ad2e089b-ba80-477b-92d1-c183f11082c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "new_chat = {\n",
    "    \"role\": \"user\",\n",
    "    \"content\": \"1.讲一个程序员才听得懂的冷笑话；2.今天是几号？3.明天星期几？\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "780f361d-b9e1-4343-8851-089d4c0aecde",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages.append(new_chat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "32b195bb-52ca-4b7f-a1f6-5b183ffbd58f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'content': 'Hello!', 'role': 'user'},\n",
      " {'content': 'Hello! How can I assist you today?', 'role': 'assistant'},\n",
      " {'content': '1.讲一个程序员才听得懂的冷笑话；2.今天是几号？3.明天星期几？', 'role': 'user'}]\n"
     ]
    }
   ],
   "source": [
    "from pprint import pprint\n",
    "\n",
    "pprint(messages)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "54b0532a-0099-40e3-8a3d-9dc72d6eccbd",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "edad9b8d-2b46-4cd4-ba03-51c96cc4c175",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChatCompletionMessage(content='1. 为什么程序员喜欢买冰淇淋？因为他们喜欢“冰”啊！\\n2. 今天是几号？很抱歉，我无法提供实时日期信息。\\n3. 明天是星期几？同样，我无法提供准确的明天日期信息。您可以查看手机或者其他工具来确认。有什么其他问题我可以帮助您解决吗？', role='assistant', function_call=None, tool_calls=None)\n"
     ]
    }
   ],
   "source": [
    "new_message = data.choices[0].message\n",
    "# 打印 new_messages \n",
    "print(new_message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "bedc91c2-4216-4686-b66c-df012a9778c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 为什么程序员喜欢买冰淇淋？因为他们喜欢“冰”啊！\n",
      "2. 今天是几号？很抱歉，我无法提供实时日期信息。\n",
      "3. 明天是星期几？同样，我无法提供准确的明天日期信息。您可以查看手机或者其他工具来确认。有什么其他问题我可以帮助您解决吗？\n"
     ]
    }
   ],
   "source": [
    "# 打印 new_messages 内容\n",
    "print(new_message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "877f2ff6-8bac-43a9-a827-e472c5698ed4",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "903ec93e-fba9-403e-bfe4-b749f91abb0c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "7f417580-7810-4f0e-ad5c-6d2e0f9e7f42",
   "metadata": {},
   "source": [
    "## 使用多种身份聊天对话\n",
    "\n",
    "目前`role`参数支持3类身份： `system`, `user` `assistant`:\n",
    "\n",
    "\n",
    "![](images/chat_completion_api.png)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "0981fe4b-410d-4d70-b07c-78a88e46b7af",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造聊天记录\n",
    "messages=[\n",
    "    {\"role\": \"system\", \"content\": \"你是一个乐于助人的体育界专家。\"},\n",
    "    {\"role\": \"user\", \"content\": \"2008年奥运会是在哪里举行的？\"},\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "7d135caf-b778-4d50-b738-a429398c6eaa",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "e97b0145-af2f-47bb-865f-9b2a8f4e6353",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2008年夏季奥运会在中国北京举行。\n"
     ]
    }
   ],
   "source": [
    "message = data.choices[0].message.content\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "fd56c185-b6e0-4ade-8236-9e2549182ab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加 GPT 返回结果到聊天记录\n",
    "messages.append({\"role\": \"assistant\", \"content\": message})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "a860210e-be0d-468e-8845-8ffceaecb034",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'system', 'content': '你是一个乐于助人的体育界专家。'},\n",
       " {'role': 'user', 'content': '2008年奥运会是在哪里举行的？'},\n",
       " {'role': 'assistant', 'content': '2008年夏季奥运会在中国北京举行。'}]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "99bae857-2854-4090-8a4d-8e1930f70464",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 第二轮对话\n",
    "messages.append({\"role\": \"user\", \"content\": \"1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "f07bbb71-fe19-4582-b1f3-3ee994fcec0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'system', 'content': '你是一个乐于助人的体育界专家。'},\n",
       " {'role': 'user', 'content': '2008年奥运会是在哪里举行的？'},\n",
       " {'role': 'assistant', 'content': '2008年夏季奥运会在中国北京举行。'},\n",
       " {'role': 'user', 'content': '1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？'}]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "a138da7f-b5b3-40a1-b30b-4e6b0c8e249f",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f531bc4d-3eeb-49f7-b717-0986f2b4af2c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 2008年夏季奥运会中，金牌最多的国家是中国，共获得51枚金牌。\n",
      "2. 2008年夏季奥运会中，奖牌最多的国家是中国，共获得100枚奖牌（51枚金牌、21枚银牌、28枚铜牌）。\n"
     ]
    }
   ],
   "source": [
    "message = data.choices[0].message.content\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "3500811e-3a80-4ed0-9770-a1f761dfab6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=[{'role': 'user', 'content': '1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？'}]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "cd59b92d-8362-4215-8865-82fe5cafce56",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1. 根据2021年东京奥运会的数据，金牌最多的国家是美国。\\n\\n2. 根据2021年东京奥运会的数据，奖牌最多的国家是美国。'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.choices[0].message.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25220ddb-b894-41b0-a36f-aadfc18d1b23",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
